// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matheus Cavalcante <matheusd@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>
//         Matteo Perotti <mperotti@iis.ee.ethz.ch>

#include "vector_macros.h"
#include "float_macros.h"

// Simple random test with similar values
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //              -15.5625,  95.7500, -42.4375,  30.7188, -50.7500, -90.2500, -95.5000,  29.5938, -41.4062, -94.0000,  34.3438, -69.5625,  31.5625, -75.0625,  46.2500, -63.6875
  VLOAD_16(v2,     0xcbc8,  0x55fc,  0xd14e,  0x4fae,  0xd258,  0xd5a4,  0xd5f8,  0x4f66,  0xd12d,  0xd5e0,  0x504b,  0xd459,  0x4fe4,  0xd4b1,  0x51c8,  0xd3f6);
  //               57.2500,  43.2812, -49.4062, -53.5625, -54.7812, -12.1406,  92.1875,  67.1875, -19.7656, -41.2812,  98.0625, -41.9062,  10.1719, -84.6250, -7.1016,  62.8750
  VLOAD_16(v6,     0x5328,  0x5169,  0xd22d,  0xd2b2,  0xd2d9,  0xca12,  0x55c3,  0x5433,  0xccf1,  0xd129,  0x5621,  0xd13d,  0x4916,  0xd54a,  0xc71a,  0x53dc);
  asm volatile("vfwsub.vv v4, v2, v6");
  //              -72.81250000,  52.46875000,  6.96875000,  84.28125000,  4.03125000, -78.10937500, -187.68750000, -37.59375000, -21.64062500, -52.71875000, -63.71875000, -27.65625000,  21.39062500,  9.56250000,  53.35156250, -126.56250000
  VCMP_U32(1, v4,  0xc291a000,  0x4251e000,  0x40df0000,  0x42a89000,  0x40810000,  0xc29c3800,  0xc33bb000,  0xc2166000,  0xc1ad2000,  0xc252e000,  0xc27ee000,  0xc1dd4000,  0x41ab2000,  0x41190000,  0x42556800,  0xc2fd2000);

  VSET(16, e32, m1);
  //               74632.77343750, -65636.60937500,  16165.84765625, -17815.85937500, -85604.03125000, -76754.03125000,  21778.01171875, -70512.52343750,  85301.90625000, -8385.11035156,  98258.05468750, -50421.53125000,  69842.53906250, -65219.96093750, -65266.08984375, -90740.60156250
  VLOAD_32(v2,     0x4791c463,  0xc780324e,  0x467c9764,  0xc68b2fb8,  0xc7a73204,  0xc795e904,  0x46aa2406,  0xc789b843,  0x47a69af4,  0xc6030471,  0x47bfe907,  0xc744f588,  0x47886945,  0xc77ec3f6,  0xc77ef217,  0xc7b13a4d);
  //               5391.72216797, -90760.36718750, -22961.19531250,  12708.62500000,  87107.59375000,  54867.48437500,  55424.39453125, -71436.00781250, -61505.46484375,  57701.78906250, -81581.38281250,  53319.19531250, -86229.57031250,  44376.69531250,  46809.38671875, -92887.27343750
  VLOAD_32(v6,     0x45a87dc7,  0xc7b1442f,  0xc6b36264,  0x46469280,  0x47aa21cc,  0x4756537c,  0x47588065,  0xc78b8601,  0xc7704177,  0x476165ca,  0xc79f56b1,  0x47504732,  0xc7a86ac9,  0x472d58b2,  0x4736d963,  0xc7b56ba3);
  asm volatile("vfwsub.vv v4, v2, v6");
  //               69241.0512695312500000,  25123.7578125000000000,  39127.0429687500000000, -30524.4843750000000000, -172711.6250000000000000, -131621.5156250000000000, -33646.3828125000000000,  923.4843750000000000,  146807.3710937500000000, -66086.8994140625000000,  179839.4375000000000000, -103740.7265625000000000,  156072.1093750000000000, -109596.6562500000000000, -112075.4765625000000000,  2146.6718750000000000
  VCMP_U64(2, v4,  0x40f0e790d2000000,  0x40d888f080000000,  0x40e31ae160000000,  0xc0ddcf1f00000000,  0xc105153d00000000,  0xc100112c20000000,  0xc0e06dcc40000000,  0x408cdbe000000000,  0x4101ebbaf8000000,  0xc0f0226e64000000,  0x4105f3fb80000000,  0xc0f953cba0000000,  0x41030d40e0000000,  0xc0fac1ca80000000,  0xc0fb5cb7a0000000,  0x40a0c55800000000);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //              -15.5625,  95.7500, -42.4375,  30.7188, -50.7500, -90.2500, -95.5000,  29.5938, -41.4062, -94.0000,  34.3438, -69.5625,  31.5625, -75.0625,  46.2500, -63.6875
  VLOAD_16(v2,     0xcbc8,  0x55fc,  0xd14e,  0x4fae,  0xd258,  0xd5a4,  0xd5f8,  0x4f66,  0xd12d,  0xd5e0,  0x504b,  0xd459,  0x4fe4,  0xd4b1,  0x51c8,  0xd3f6);
  //               57.2500,  43.2812, -49.4062, -53.5625, -54.7812, -12.1406,  92.1875,  67.1875, -19.7656, -41.2812,  98.0625, -41.9062,  10.1719, -84.6250, -7.1016,  62.8750
  VLOAD_16(v6,     0x5328,  0x5169,  0xd22d,  0xd2b2,  0xd2d9,  0xca12,  0x55c3,  0x5433,  0xccf1,  0xd129,  0x5621,  0xd13d,  0x4916,  0xd54a,  0xc71a,  0x53dc);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.vv v4, v2, v6, v0.t");
  //               0.00000000,  52.46875000,  0.00000000,  84.28125000,  0.00000000, -78.10937500,  0.00000000, -37.59375000,  0.00000000, -52.71875000,  0.00000000, -27.65625000,  0.00000000,  9.56250000,  0.00000000, -126.56250000
  VCMP_U32(3, v4,  0x0,  0x4251e000,  0x0,  0x42a89000,  0x0,  0xc29c3800,  0x0,  0xc2166000,  0x0,  0xc252e000,  0x0,  0xc1dd4000,  0x0,  0x41190000,  0x0,  0xc2fd2000);

  VSET(16, e32, m1);
  //               74632.77343750, -65636.60937500,  16165.84765625, -17815.85937500, -85604.03125000, -76754.03125000,  21778.01171875, -70512.52343750,  85301.90625000, -8385.11035156,  98258.05468750, -50421.53125000,  69842.53906250, -65219.96093750, -65266.08984375, -90740.60156250
  VLOAD_32(v2,     0x4791c463,  0xc780324e,  0x467c9764,  0xc68b2fb8,  0xc7a73204,  0xc795e904,  0x46aa2406,  0xc789b843,  0x47a69af4,  0xc6030471,  0x47bfe907,  0xc744f588,  0x47886945,  0xc77ec3f6,  0xc77ef217,  0xc7b13a4d);
  //               5391.72216797, -90760.36718750, -22961.19531250,  12708.62500000,  87107.59375000,  54867.48437500,  55424.39453125, -71436.00781250, -61505.46484375,  57701.78906250, -81581.38281250,  53319.19531250, -86229.57031250,  44376.69531250,  46809.38671875, -92887.27343750
  VLOAD_32(v6,     0x45a87dc7,  0xc7b1442f,  0xc6b36264,  0x46469280,  0x47aa21cc,  0x4756537c,  0x47588065,  0xc78b8601,  0xc7704177,  0x476165ca,  0xc79f56b1,  0x47504732,  0xc7a86ac9,  0x472d58b2,  0x4736d963,  0xc7b56ba3);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.vv v4, v2, v6, v0.t");
  //               0.0000000000000000,  25123.7578125000000000,  0.0000000000000000, -30524.4843750000000000,  0.0000000000000000, -131621.5156250000000000,  0.0000000000000000,  923.4843750000000000,  0.0000000000000000, -66086.8994140625000000,  0.0000000000000000, -103740.7265625000000000,  0.0000000000000000, -109596.6562500000000000,  0.0000000000000000,  2146.6718750000000000
  VCMP_U64(4, v4,  0x0,  0x40d888f080000000,  0x0,  0xc0ddcf1f00000000,  0x0,  0xc100112c20000000,  0x0,  0x408cdbe000000000,  0x0,  0xc0f0226e64000000,  0x0,  0xc0f953cba0000000,  0x0,  0xc0fac1ca80000000,  0x0,  0x40a0c55800000000);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              36.4375
  BOX_HALF_IN_DOUBLE(dscalar_16,  0x508e);
  //               69.8125, -37.3125, -77.2500,  32.7188, -83.0000,  76.3125,  14.9375,  72.5000,  39.6250, -61.2188,  36.3438,  93.5000, -87.1875, -6.9258,  25.1094, -96.8750
  VLOAD_16(v2,     0x545d,  0xd0aa,  0xd4d4,  0x5017,  0xd530,  0x54c5,  0x4b78,  0x5488,  0x50f4,  0xd3a7,  0x508b,  0x55d8,  0xd573,  0xc6ed,  0x4e47,  0xd60e);
  asm volatile("vfwsub.vf v4, v2, %[A]" :: [A] "f" (dscalar_16));
  //               33.37500000, -73.75000000, -113.68750000, -3.71875000, -119.43750000,  39.87500000, -21.50000000,  36.06250000,  3.18750000, -97.65625000, -0.09375000,  57.06250000, -123.62500000, -43.36328125, -11.32812500, -133.31250000
  VCMP_U32(5, v4,  0x42058000,  0xc2938000,  0xc2e36000,  0xc06e0000,  0xc2eee000,  0x421f8000,  0xc1ac0000,  0x42104000,  0x404c0000,  0xc2c35000,  0xbdc00000,  0x42644000,  0xc2f74000,  0xc22d7400,  0xc1354000,  0xc3055000);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -138614.20312500
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xc8075d8d);
  //               473107.93750000,  161975.07812500, -173044.89062500, -322046.09375000, -485607.56250000, -613808.37500000, -182790.53125000,  121114.44531250, -958537.81250000,  295217.40625000,  281159.84375000, -735195.87500000, -783982.56250000,  420983.65625000,  954426.12500000, -297052.53125000
  VLOAD_32(v2,     0x48e7027e,  0x481e2dc5,  0xc828fd39,  0xc89d3fc3,  0xc8ed1cf2,  0xc915db06,  0xc83281a2,  0x47ec8d39,  0xc96a049d,  0x4890262d,  0x488948fb,  0xc9337dbe,  0xc93f66e9,  0x48cd8ef5,  0x496903a2,  0xc8910b91);
  asm volatile("vfwsub.vf v4, v2, %[A]" :: [A] "f" (dscalar_32));
  //               611722.1406250000000000,  300589.2812500000000000, -34430.6875000000000000, -183431.8906250000000000, -346993.3593750000000000, -475194.1718750000000000, -44176.3281250000000000,  259728.6484375000000000, -819923.6093750000000000,  433831.6093750000000000,  419774.0468750000000000, -596581.6718750000000000, -645368.3593750000000000,  559597.8593750000000000,  1093040.3281250000000000, -158438.3281250000000000
  VCMP_U64(6, v4,  0x4122ab1448000000,  0x411258b520000000,  0xc0e0cfd600000000,  0xc106643f20000000,  0xc1152dc570000000,  0xc11d00e8b0000000,  0xc0e5920a80000000,  0x410fb48530000000,  0xc12905a738000000,  0x411a7a9e70000000,  0x41199ef830000000,  0xc12234cb58000000,  0xc123b1f0b8000000,  0x412113dbb8000000,  0x4130adb054000000,  0xc1035732a0000000);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              36.4375
  BOX_HALF_IN_DOUBLE(dscalar_16,  0x508e);
  //                69.8125, -37.3125, -77.2500,  32.7188, -83.0000,  76.3125,  14.9375,  72.5000,  39.6250, -61.2188,  36.3438,  93.5000, -87.1875, -6.9258,  25.1094, -96.8750
  VLOAD_16(v2,      0x545d,  0xd0aa,  0xd4d4,  0x5017,  0xd530,  0x54c5,  0x4b78,  0x5488,  0x50f4,  0xd3a7,  0x508b,  0x55d8,  0xd573,  0xc6ed,  0x4e47,  0xd60e);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.vf v4, v2, %[A], v0.t" :: [A] "f" (dscalar_16));
  //                0.00000000, -73.75000000,  0.00000000, -3.71875000,  0.00000000,  39.87500000,  0.00000000,  36.06250000,  0.00000000, -97.65625000,  0.00000000,  57.06250000,  0.00000000, -43.36328125,  0.00000000, -133.31250000
  VCMP_U32(7, v4,  0x0,  0xc2938000,  0x0,  0xc06e0000,  0x0,  0x421f8000,  0x0,  0x42104000,  0x0,  0xc2c35000,  0x0,  0x42644000,  0x0,  0xc22d7400,  0x0,  0xc3055000);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -138614.20312500
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xc8075d8d);
  //                473107.93750000,  161975.07812500, -173044.89062500, -322046.09375000, -485607.56250000, -613808.37500000, -182790.53125000,  121114.44531250, -958537.81250000,  295217.40625000,  281159.84375000, -735195.87500000, -783982.56250000,  420983.65625000,  954426.12500000, -297052.53125000
  VLOAD_32(v2,      0x48e7027e,  0x481e2dc5,  0xc828fd39,  0xc89d3fc3,  0xc8ed1cf2,  0xc915db06,  0xc83281a2,  0x47ec8d39,  0xc96a049d,  0x4890262d,  0x488948fb,  0xc9337dbe,  0xc93f66e9,  0x48cd8ef5,  0x496903a2,  0xc8910b91);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.vf v4, v2, %[A], v0.t" :: [A] "f" (dscalar_32));
  //                0.0000000000000000,  300589.2812500000000000,  0.0000000000000000, -183431.8906250000000000,  0.0000000000000000, -475194.1718750000000000,  0.0000000000000000,  259728.6484375000000000,  0.0000000000000000,  433831.6093750000000000,  0.0000000000000000, -596581.6718750000000000,  0.0000000000000000,  559597.8593750000000000,  0.0000000000000000, -158438.3281250000000000
  VCMP_U64(8, v4,  0x0,  0x411258b520000000,  0x0,  0xc106643f20000000,  0x0,  0xc11d00e8b0000000,  0x0,  0x410fb48530000000,  0x0,  0x411a7a9e70000000,  0x0,  0xc12234cb58000000,  0x0,  0x412113dbb8000000,  0x0,  0xc1035732a0000000);
};
// Simple random test with similar values
void TEST_CASE5(void) {
  VSET(16, e16, m1);
  //              -92.15529633,  27.66998672, -5.68499708,  78.95133209,  57.52299500,  15.45270920,  50.26883316,  46.63587189,  71.16806793, -80.68485260, -22.34193420,  40.17027283,  93.54611969,  25.86016083,  41.82838821,  82.50254822
  VLOAD_32(v2,     0xc2b84f83,  0x41dd5c22,  0xc0b5eb7f,  0x429de715,  0x4266178c,  0x41773e4c,  0x42491349,  0x423a8b22,  0x428e560d,  0xc2a15ea5,  0xc1b2bc48,  0x4220ae5c,  0x42bb179d,  0x41cee19c,  0x42275045,  0x42a5014e);
  //              -72.5625, -83.4375,  28.8281,  33.5938, -85.7500,  67.5000,  91.0625, -91.8750, -9.2578, -64.2500, -58.6250,  50.3438, -70.5000,  36.6250,  5.7930,  86.6875
  VLOAD_16(v6,     0xd489,  0xd537,  0x4f35,  0x5033,  0xd55c,  0x5438,  0x55b1,  0xd5be,  0xc8a1,  0xd404,  0xd354,  0x524b,  0xd468,  0x5094,  0x45cb,  0x556b);
  asm volatile("vfwsub.wv v4, v2, v6");
  //              -19.59279633,  111.10748291, -34.51312256,  45.35758209,  143.27299500, -52.04729080, -40.79366684,  138.51086426,  80.42588043, -16.43485260,  36.28306580, -10.17347717,  164.04611206, -10.76483917,  36.03541946, -4.18495178
  VCMP_U32(9, v4,  0xc19cbe0c,  0x42de3708,  0xc20a0d70,  0x42356e2a,  0x430f45e3,  0xc250306d,  0xc2232cb7,  0x430a82c8,  0x42a0da0d,  0xc1837a94,  0x421121dc,  0xc122c690,  0x43240bce,  0xc12c3cc8,  0x42102445,  0xc085eb20);

  VSET(16, e32, m1);
  //              -79494.9435096215456724,  81629.4152202270051930,  60506.1876363231276628, -81020.4028176319407066, -6814.2587861350475578,  11974.4045779409498209,  97975.7066144426062237, -93357.8779376419261098,  95959.4397212496260181, -58528.4286213813902577,  28958.3763895476586185, -36387.3665319164574612, -90399.7993234442838002, -78772.1006454367889091, -62854.6154750282003079,  37858.6386504948022775
  VLOAD_64(v2,     0xc0f3686f189d8b80,  0x40f3edd6a4bdf6fa,  0x40ed8b46011de3ec,  0xc0f3c7c671f0e6b7,  0xc0ba9e423fcee2b0,  0x40c76333c935c088,  0x40f7eb7b4e4af21e,  0xc0f6cade0c085740,  0x40f76d7709192628,  0xc0ec940db7442fee,  0x40dc479816c42f70,  0xc0e1c46bbaa12444,  0xc0f611fcca076142,  0xc0f33b419c3e63b8,  0xc0eeb0d3b1f8afb4,  0x40e27c546fd32998);
  //               95822.63281250,  21789.49804688, -42409.42968750,  60172.89062500, -46359.57812500, -71236.33593750,  4124.35888672, -80527.00000000,  27430.70507812,  39975.67578125, -71197.53125000, -66640.12500000,  47459.75390625, -34899.84375000, -21371.85937500,  17582.65820312
  VLOAD_32(v6,     0x47bb2751,  0x46aa3aff,  0xc725a96e,  0x476b0ce4,  0xc7351794,  0xc78b222b,  0x4580e2df,  0xc79d4780,  0x46d64d69,  0x471c27ad,  0xc78b0ec4,  0xc7822810,  0x473963c1,  0xc70853d8,  0xc6a6f7b8,  0x46895d51);
  asm volatile("vfwsub.wv v4, v2, v6");
  //              -175317.5763221215456724,  59839.9171733520051930,  102915.6173238231276628, -141193.2934426319552585,  39545.3193388649524422,  83210.7405154409498209,  93851.3477277238562237, -12830.8779376419261098,  68528.7346431246260181, -98504.1044026313902577,  100155.9076395476586185,  30252.7584680835425388, -137859.5532296942838002, -43872.2568954367889091, -41482.7561000282003079,  20275.9804473698022775
  VCMP_U64(10, v4,  0xc10566ac9c4ec5c0,  0x40ed37fd597bedf4,  0x40f92039e08ef1f6,  0xc1013c4a58f8735c,  0x40e34f2a380623aa,  0x40f450abd926b811,  0x40f6e9b5904af21e,  0xc0c90f706042ba00,  0x40f0bb0bc1192628,  0xc0f80c81aba217f7,  0x40f873be85b10bdc,  0x40dd8b308abdb778,  0xc100d41c6d03b0a1,  0xc0e56c08387cc770,  0xc0e4415831f8afb4,  0x40d3ccfebfa65330);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE6(void) {
  VSET(16, e16, m1);
  //              -92.15529633,  27.66998672, -5.68499708,  78.95133209,  57.52299500,  15.45270920,  50.26883316,  46.63587189,  71.16806793, -80.68485260, -22.34193420,  40.17027283,  93.54611969,  25.86016083,  41.82838821,  82.50254822
  VLOAD_32(v2,     0xc2b84f83,  0x41dd5c22,  0xc0b5eb7f,  0x429de715,  0x4266178c,  0x41773e4c,  0x42491349,  0x423a8b22,  0x428e560d,  0xc2a15ea5,  0xc1b2bc48,  0x4220ae5c,  0x42bb179d,  0x41cee19c,  0x42275045,  0x42a5014e);
  //              -72.5625, -83.4375,  28.8281,  33.5938, -85.7500,  67.5000,  91.0625, -91.8750, -9.2578, -64.2500, -58.6250,  50.3438, -70.5000,  36.6250,  5.7930,  86.6875
  VLOAD_16(v6,     0xd489,  0xd537,  0x4f35,  0x5033,  0xd55c,  0x5438,  0x55b1,  0xd5be,  0xc8a1,  0xd404,  0xd354,  0x524b,  0xd468,  0x5094,  0x45cb,  0x556b);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.wv v4, v2, v6, v0.t");
  //               0.00000000,  111.10748291,  0.00000000,  45.35758209,  0.00000000, -52.04729080,  0.00000000,  138.51086426,  0.00000000, -16.43485260,  0.00000000, -10.17347717,  0.00000000, -10.76483917,  0.00000000, -4.18495178
  VCMP_U32(11, v4,  0x0,  0x42de3708,  0x0,  0x42356e2a,  0x0,  0xc250306d,  0x0,  0x430a82c8,  0x0,  0xc1837a94,  0x0,  0xc122c690,  0x0,  0xc12c3cc8,  0x0,  0xc085eb20);

  VSET(16, e32, m1);
  //              -79494.9435096215456724,  81629.4152202270051930,  60506.1876363231276628, -81020.4028176319407066, -6814.2587861350475578,  11974.4045779409498209,  97975.7066144426062237, -93357.8779376419261098,  95959.4397212496260181, -58528.4286213813902577,  28958.3763895476586185, -36387.3665319164574612, -90399.7993234442838002, -78772.1006454367889091, -62854.6154750282003079,  37858.6386504948022775
  VLOAD_64(v2,     0xc0f3686f189d8b80,  0x40f3edd6a4bdf6fa,  0x40ed8b46011de3ec,  0xc0f3c7c671f0e6b7,  0xc0ba9e423fcee2b0,  0x40c76333c935c088,  0x40f7eb7b4e4af21e,  0xc0f6cade0c085740,  0x40f76d7709192628,  0xc0ec940db7442fee,  0x40dc479816c42f70,  0xc0e1c46bbaa12444,  0xc0f611fcca076142,  0xc0f33b419c3e63b8,  0xc0eeb0d3b1f8afb4,  0x40e27c546fd32998);
  //               95822.63281250,  21789.49804688, -42409.42968750,  60172.89062500, -46359.57812500, -71236.33593750,  4124.35888672, -80527.00000000,  27430.70507812,  39975.67578125, -71197.53125000, -66640.12500000,  47459.75390625, -34899.84375000, -21371.85937500,  17582.65820312
  VLOAD_32(v6,     0x47bb2751,  0x46aa3aff,  0xc725a96e,  0x476b0ce4,  0xc7351794,  0xc78b222b,  0x4580e2df,  0xc79d4780,  0x46d64d69,  0x471c27ad,  0xc78b0ec4,  0xc7822810,  0x473963c1,  0xc70853d8,  0xc6a6f7b8,  0x46895d51);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.wv v4, v2, v6, v0.t");
  //               0.0000000000000000,  59839.9171733520051930,  0.0000000000000000, -141193.2934426319552585,  0.0000000000000000,  83210.7405154409498209,  0.0000000000000000, -12830.8779376419261098,  0.0000000000000000, -98504.1044026313902577,  0.0000000000000000,  30252.7584680835425388,  0.0000000000000000, -43872.2568954367889091,  0.0000000000000000,  20275.9804473698022775
  VCMP_U64(12, v4,  0x0,  0x40ed37fd597bedf4,  0x0,  0xc1013c4a58f8735c,  0x0,  0x40f450abd926b811,  0x0,  0xc0c90f706042ba00,  0x0,  0xc0f80c81aba217f7,  0x0,  0x40dd8b308abdb778,  0x0,  0xc0e56c08387cc770,  0x0,  0x40d3ccfebfa65330);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE7(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //              -8.76965809,  55.45920181,  71.29286957, -84.65414429, -81.93881226,  75.13192749, -75.44019318, -48.81898499,  0.10306206, -25.18898392,  49.68006516,  72.66278076, -24.90880966, -32.59431458,  14.58876038, -55.07221603
  VLOAD_32(v2,     0xc10c5085,  0x425dd639,  0x428e95f3,  0xc2a94eec,  0xc2a3e0ac,  0x4296438c,  0xc296e161,  0xc24346a4,  0x3dd31233,  0xc1c9830a,  0x4246b863,  0x42915358,  0xc1c7453e,  0xc2026094,  0x41696b90,  0xc25c49f3);
  //                              34.7812
  BOX_HALF_IN_DOUBLE(dscalar_16,  0x5059);
  asm volatile("vfwsub.wf v4, v2, %[A]" :: [A] "f" (dscalar_16));
  //              -43.55090714,  20.67795181,  36.51161957, -119.43539429, -116.72006226,  40.35067749, -110.22144318, -83.60023499, -34.67818832, -59.97023392,  14.89881516,  37.88153076, -59.69005966, -67.37556458, -20.19248962, -89.85346985
  VCMP_U32(13, v4,  0xc22e3421,  0x41a56c72,  0x42120be6,  0xc2eedeec,  0xc2e970ac,  0x42216718,  0xc2dc7161,  0xc2a73352,  0xc20ab677,  0xc26fe185,  0x416e618c,  0x421786b0,  0xc26ec29f,  0xc286c04a,  0xc1a18a38,  0xc2b3b4fa);

  VSET(16, e32, m1);
  double dscalar_32;
  //               322189.5706008458510041,  914899.9451866354793310, -620811.0881863175891340, -456926.2657179111847654, -549945.8717311944346875, -386814.9759888321859762,  748677.5319772073999047,  821298.7777016961481422,  968861.0598710167687386, -343694.5546012039994821, -782815.4022130169905722, -561429.7869165195152164,  755371.9691831718664616, -954868.1761190977413207, -606267.0986005428712815,  818185.4808380266185850
  VLOAD_64(v2,     0x4113aa36484b9690,  0x412beba7e3ef80b0,  0xc122f2162d26c1cc,  0xc11be37910185b2a,  0xc120c873be538d16,  0xc1179bfbe7699dce,  0x4126d90b105f5108,  0x412910658e2eeaae,  0x412d913a1ea769f6,  0xc114fa3a37e960c6,  0xc127e3becdeedd54,  0xc121222b92e6b8d8,  0x41270d57f038c6d6,  0xc12d23e85a2c484a,  0xc1228076327bc536,  0x4128f812f63066de);
  //                              -83388.08593750
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xc7a2de0b);
  asm volatile("vfwsub.wf v4, v2, %[A]" :: [A] "f" (dscalar_32));
  //               405577.6565383458510041,  998288.0311241354793310, -537423.0022488175891340, -373538.1797804111847654, -466557.7857936944346875, -303426.8900513321859762,  832065.6179147073999047,  904686.8636391961481422,  1052249.1458085167687386, -260306.4686637039994821, -699427.3162755169905722, -478041.7009790195152164,  838760.0551206718664616, -871480.0901815977413207, -522879.0126630428712815,  901573.5667755266185850
  VCMP_U64(14, v4,  0x4118c126a04b9690,  0x412e77200fef80b0,  0xc120669e0126c1cc,  0xc116cc88b8185b2a,  0xc11c79f724a71a2c,  0xc112850b8f699dce,  0x412964833c5f5108,  0x412b9bddba2eeaae,  0x41300e592553b4fb,  0xc10fc693bfd2c18c,  0xc1255846a1eedd54,  0xc11d2d66cdcd71b0,  0x412998d01c38c6d6,  0xc12a98702e2c484a,  0xc11fe9fc0cf78a6c,  0x412b838b223066de);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE8(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //               -8.76965809,  55.45920181,  71.29286957, -84.65414429, -81.93881226,  75.13192749, -75.44019318, -48.81898499,  0.10306206, -25.18898392,  49.68006516,  72.66278076, -24.90880966, -32.59431458,  14.58876038, -55.07221603
  VLOAD_32(v2,      0xc10c5085,  0x425dd639,  0x428e95f3,  0xc2a94eec,  0xc2a3e0ac,  0x4296438c,  0xc296e161,  0xc24346a4,  0x3dd31233,  0xc1c9830a,  0x4246b863,  0x42915358,  0xc1c7453e,  0xc2026094,  0x41696b90,  0xc25c49f3);
  //                              34.7812
  BOX_HALF_IN_DOUBLE(dscalar_16,  0x5059);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.wf v4, v2, %[A], v0.t" :: [A] "f" (dscalar_16));
  //                0.00000000,  20.67795181,  0.00000000, -119.43539429,  0.00000000,  40.35067749,  0.00000000, -83.60023499,  0.00000000, -59.97023392,  0.00000000,  37.88153076,  0.00000000, -67.37556458,  0.00000000, -89.85346985
  VCMP_U32(15, v4,  0x0,  0x41a56c72,  0x0,  0xc2eedeec,  0x0,  0x42216718,  0x0,  0xc2a73352,  0x0,  0xc26fe185,  0x0,  0x421786b0,  0x0,  0xc286c04a,  0x0,  0xc2b3b4fa);

  VSET(16, e32, m1);
  double dscalar_32;
  //                322189.5706008458510041,  914899.9451866354793310, -620811.0881863175891340, -456926.2657179111847654, -549945.8717311944346875, -386814.9759888321859762,  748677.5319772073999047,  821298.7777016961481422,  968861.0598710167687386, -343694.5546012039994821, -782815.4022130169905722, -561429.7869165195152164,  755371.9691831718664616, -954868.1761190977413207, -606267.0986005428712815,  818185.4808380266185850
  VLOAD_64(v2,      0x4113aa36484b9690,  0x412beba7e3ef80b0,  0xc122f2162d26c1cc,  0xc11be37910185b2a,  0xc120c873be538d16,  0xc1179bfbe7699dce,  0x4126d90b105f5108,  0x412910658e2eeaae,  0x412d913a1ea769f6,  0xc114fa3a37e960c6,  0xc127e3becdeedd54,  0xc121222b92e6b8d8,  0x41270d57f038c6d6,  0xc12d23e85a2c484a,  0xc1228076327bc536,  0x4128f812f63066de);
  //                              -83388.08593750
  BOX_FLOAT_IN_DOUBLE(dscalar_32,  0xc7a2de0b);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwsub.wf v4, v2, %[A], v0.t" :: [A] "f" (dscalar_32));
  //                0.0000000000000000,  998288.0311241354793310,  0.0000000000000000, -373538.1797804111847654,  0.0000000000000000, -303426.8900513321859762,  0.0000000000000000,  904686.8636391961481422,  0.0000000000000000, -260306.4686637039994821,  0.0000000000000000, -478041.7009790195152164,  0.0000000000000000, -871480.0901815977413207,  0.0000000000000000,  901573.5667755266185850
  VCMP_U64(16, v4,  0x0,  0x412e77200fef80b0,  0x0,  0xc116cc88b8185b2a,  0x0,  0xc112850b8f699dce,  0x0,  0x412b9bddba2eeaae,  0x0,  0xc10fc693bfd2c18c,  0x0,  0xc11d2d66cdcd71b0,  0x0,  0xc12a98702e2c484a,  0x0,  0x412b838b223066de);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  TEST_CASE5();
  TEST_CASE6();
  TEST_CASE7();
  TEST_CASE8();

  EXIT_CHECK();
}


